package cn.bingo.yunsj.mail;

import cn.bingo.yunsj.XWPF.XHTMLConverter;
import cn.bingo.yunsj.common.exception.EmException;
import cn.bingo.yunsj.common.exception.OwnException;
import cn.bingo.yunsj.mail.model.FileProperties;
import cn.bingo.yunsj.mail.model.NewMailModel;
import cn.bingo.yunsj.mail.model.ImageModel;
import fr.opensagres.poi.xwpf.converter.core.BasicURIResolver;
import fr.opensagres.poi.xwpf.converter.core.FileImageExtractor;
import fr.opensagres.poi.xwpf.converter.xhtml.XHTMLOptions;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.converter.WordToHtmlConverter;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

// 参数处理之后，就是将word转换成html
public class WordToHtml {

    private String imagePath;

    private String imageFileInfo;

    private List<ImageModel> list = new ArrayList<>();

    private OutputStreamWriter outputStreamWriter = null;

    private BufferedReader br = null;

    private static final Logger logger = LoggerFactory.getLogger(WordToHtml.class);

    // 初始化一些参数
    public WordToHtml() {
        imagePath = FileProperties.getImagePath();
        imageFileInfo = FileProperties.getImageFileInfo();
        logger.info("图片路径："+imagePath);
        logger.info("图片信息路径："+imageFileInfo);
    }

    //word转换成html
    public void doWordToHtml(NewMailModel newMailModel) throws ParserConfigurationException, TransformerException, IOException {
        logger.info("开始将word转换成html");
        if (StringUtils.isBlank(newMailModel.getWordPath())) {
            //到时再进行异常处理
            throw new OwnException(EmException.PARAM_EXCPTION);
        }

        if (newMailModel.getWordPath().endsWith("docx")) { // 2007 及以后
            docx(newMailModel);
        } else { // 2003 之前
            doc(newMailModel);
        }
        destory();  //资源销毁处理


        // 调用html解析
        HtmlParse htmlParse = new HtmlParse();
        htmlParse.doHtmlParse(newMailModel,list);
    }

    private void docx(NewMailModel newMailModel) throws IOException {
        logger.info("开始解析docx");
        XWPFDocument document = new XWPFDocument(
                new FileInputStream(newMailModel.getWordPath()));

        XHTMLOptions options = XHTMLOptions.create();

        // 存放图片的文件夹
        options.setExtractor(
                new FileImageExtractor(
                        new File(imagePath)));

        // html中图片的路径
        options.URIResolver(
                new BasicURIResolver(imagePath));

        outputStreamWriter = new OutputStreamWriter(
                new FileOutputStream(newMailModel.getHtmlPath()), "utf-8");

        XHTMLConverter xhtmlConverter = (XHTMLConverter) XHTMLConverter.getInstance();

        //将所需要得图片名称写入到了文件里面
        xhtmlConverter.convert(document, outputStreamWriter, options);

        //将文件里面得图片信息读取出来
        br = new BufferedReader(
                new InputStreamReader(
                        new FileInputStream(imageFileInfo), "utf-8"));

        String s = null;
        while ((s = br.readLine()) != null) {
            ImageModel imageModel = new ImageModel() {{
                setWordName(newMailModel.getWordPath());
            }};
            imageModel.setImageName(s);
            imageModel.setImagePath(imagePath + "word/media/" + s);
            list.add(imageModel);
        }

    }

    private void doc(NewMailModel newMailModel) throws IOException, ParserConfigurationException, TransformerException {
        logger.info("开始解析doc");
        HWPFDocument wordDocument = new HWPFDocument(
                new FileInputStream(newMailModel.getWordPath()));

        Document document = DocumentBuilderFactory
                .newInstance()
                .newDocumentBuilder()
                .newDocument();

        WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(document);

        wordToHtmlConverter.setPicturesManager((content, pictureType, name, width, height) -> {
            // 保存图片，并返回图片的绝对路径
            File imageFile = new File(imagePath);
            if (!imageFile.exists()) {
                imageFile.mkdirs();
            }
            try (FileOutputStream out = new FileOutputStream(imagePath + name)) {
                out.write(content);
            } catch (Exception e) {
                e.printStackTrace();
            }
            ImageModel imageModel = new ImageModel() {{
                setImageName(name);
                setImagePath(imagePath + name);
            }};
            list.add(imageModel);
            return imagePath + name;
        });
        wordToHtmlConverter.processDocument(wordDocument);
        Document htmlDocument = wordToHtmlConverter.getDocument();
        DOMSource domSource = new DOMSource(htmlDocument);
        StreamResult streamResult = new StreamResult(
                new FileOutputStream(newMailModel.getHtmlPath()));

        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer serializer = tf.newTransformer();
        serializer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
        serializer.setOutputProperty(OutputKeys.INDENT, "yes");
        serializer.setOutputProperty(OutputKeys.METHOD, "html");
        serializer.transform(domSource, streamResult);
    }

    // 文件流销毁
    private void destory(){
        if (br != null) {
            try {
                br.close();
            } catch (IOException e) {
                throw new OwnException(EmException.FILE_EXCPTION,"关闭失败");
            }
        }
        if(outputStreamWriter != null){
            try {
                outputStreamWriter.close();
            } catch (IOException e) {
                throw new OwnException(EmException.FILE_EXCPTION,"关闭失败");
            }
        }
    }
}
